package main

import (
	"flag"
	"fmt"
	//	"os"
	MQTT "github.com/eclipse/paho.mqtt.golang"
	"time"
	//"bufio"
	//"os"
	"log"
	"path/filepath"
	"os"
	"gopkg.in/mgo.v2"
	"github.com/liu-junyong/go-logger/logger"
	"gopkg.in/mgo.v2/bson"
	//"github.com/liu-junyong/gohelper"
	"encoding/json"
	"github.com/chzyer/readline"
	"io"
	"github.com/liu-junyong/gohelper"
	"strings"
//	"github.com/larspensjo/config"
	ini "github.com/go-ini/ini"

)


var MongoURL string
var MgoSession *mgo.Session

func MongoSession() *mgo.Session {
	defer func() {
		if r := recover(); r != nil {
			logger.Error(r)
		}
	}()

	if MgoSession == nil {
		var err error
		info, _ := mgo.ParseURL(MongoURL)
		MgoSession, err = mgo.DialWithInfo(info)
		if err != nil {
			panic(err)
		}

	}
	return MgoSession.Clone()
}



func GetUserUnionID( userid int) *map[string]interface{} {
	session := MongoSession()
	db := session.DB("")             //数据库名称
	collection := db.C("mj_players") //如果该集合已经存在的话，则直接返回

	defer func() {
		session.Close()
		if err := recover(); err != nil {
			logger.Error(err)
		}
	}()

	result := make(map[string]interface{}, 0)

	err := collection.Find(&bson.M{"_id": userid}).One(&result)
	if err != nil {
		logger.Error(err)
		return nil
	}

	return &result
}

func filterInput(r rune) (rune, bool) {
	switch r {
	// block CtrlZ feature
	case readline.CharCtrlZ:
		return r, false
	}
	return r, true
}


func main() {
	//topic := flag.String("topic", "n", "The topic name to/from which to publish/subscribe")
	//broker := flag.String("broker", "ws://127.0.0.1:56701/mqtt", "The broker URI. ex: tcp://10.10.1.1:1883")
	//password := flag.String("password", "", "The password (optional)")
	//user := flag.String("user", "", "The User (optional)")
	//id := flag.String("id", "200", "The ClientID (optional)")
	//cleansess := flag.Bool("clean", false, "Set Clean Session (default false)")
	//qos := flag.Int("qos", 0, "The Quality of Service 0,1,2 (default 0)")
	//num := flag.Int("num", 1, "The number of messages to publish or subscribe (default 1)")
	//payload := flag.String("message", "111", "The message text to publish (default empty)")
	//action := flag.String("action", "pub", "Action publish or subscribe (required)")
	//store := flag.String("store", ":memory:", "The Store Directory (default use memory store)")
	area := flag.String("area", "hunan", "选择卡区")
	uid := flag.Int("uid", 0, "请输入用户id")
	flag.Parse()

	if *uid == 0  {
		flag.Usage()
		return
	}

	dir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
	filename := dir + "/simulalogin.ini"

	cfg, e1 := ini.Load(filename)
	if e1 != nil {
		logger.Error( e1.Error() )
		return
	}

	if cfg != nil {
		MongoURL  =cfg.Section(*area).Key("url").String()
	}else{
		log.Fatalln("找不到配置：",filename,"[",*area, "]url")
	}

	userinfo := GetUserUnionID(*uid)
	if userinfo == nil {
		log.Fatalln("找不到用户：",*uid)
	}else{
		logger.Info(*userinfo)
	}


	(*userinfo)["needComp"] = 1
	(*userinfo)["version"] = "8.0.9"
	(*userinfo)["discard"] = "force"




	broker := cfg.Section(*area).Key("broker").String()
	if len(broker) < 5 {
		log.Fatalln("找不到配置：",filename,"[",*area, "]broker")
	}

	opts := MQTT.NewClientOptions()
	opts.AddBroker(broker)



	id := gohelper.Json2String( (*userinfo)["openid"] )
	if len(id) == 0 {
		id = gohelper.Json2String( (*userinfo)["unionid"] )
	}

	opts.SetClientID(id)
	opts.SetUsername("")
	opts.SetPassword("")
	opts.SetCleanSession(false)
	opts.SetProtocolVersion(3)

	client := MQTT.NewClient(opts)
	opts.SetDefaultPublishHandler(func(client MQTT.Client, msg MQTT.Message) {
		logger.Info(string(msg.Payload()))
	})

//	{"uid":625458,"data":{"room_id":419942,"is_accept":1},"code":3009}
	// {"uid":776465,"data":{"club_id":0},"code":3015}
	//{"uid":123272,"data":{"room_id":865634},"code":3100}

	callback := func(client MQTT.Client, msg MQTT.Message) {
		logger.Info(string(msg.Payload()))
		payload := string(msg.Payload())
		kuohao := strings.IndexByte(payload,'{')
		if kuohao > 0 {
			js := payload[kuohao:]
			js = strings.Replace(js,"'","\"",-1)
			data := make(map[string]interface{})
			er := json.Unmarshal( []byte(js) ,&data)
			if er == nil {
				logger.Info(data)
			}else{
				logger.Error(er)
				logger.Error( string( payload) )
			}
		}else{
			logger.Error( string( payload) )
		}
	}

	logger.Info( "开始连接：",broker )

	if token3 := client.Connect(); token3.Wait() && token3.Error() != nil {
		logger.Error( token3.Error()  )
		panic(token3.Error())
	}

	senddata := make( map[string]interface{},0 )
	senddata["data"] = *userinfo
	senddata["code"] = 2001

	js,_ := json.Marshal( &senddata )

	logger.Info( "准备订阅：",broker )

	if token2 := client.Subscribe("n", byte(0), callback); token2.Wait() && token2.Error() != nil {
		logger.Error( token2.Error()  )
		fmt.Println(token2.Error())
	}

	send := string(js)
	send = strings.Replace(send,"\n","",-1)


	logger.Info( send )
	token4 := client.Publish("n", byte(0), false, send )
	token4.Wait()



	l, err := readline.NewEx(&readline.Config{
		Prompt:          "\033[31m»\033[0m ",
		HistoryFile:     "/tmp/readline.history.txt",
		InterruptPrompt: "^C",
		EOFPrompt:       "exit",
		HistorySearchFold:   true,
		FuncFilterInputRune: filterInput,
	})
	if err != nil {
		panic(err)
	}
	defer l.Close()

	for {
		line, err := l.Readline()
		if err == readline.ErrInterrupt {
			if len(line) == 0 {
				break
			} else {
				continue
			}
		} else if err == io.EOF {
			break
		}
		token := client.Publish("n", byte(0), false, line)
		token.Wait()
	}


	log.Println("即将退出")
	time.Sleep(time.Second * 10)
}
